home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Pascal Super Library
/
Pascal Super Library (CW International)(1997).bin
/
LIBRARY
/
PBLIB1
/
UNITS
/
PBCRT.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1994-05-03
|
31KB
|
1,026 lines
{SECTION ..PbCRT }
UNIT PbCRT;
INTERFACE
uses DOS, CRT, PbMISC;
{
Description: Extenstion to CRT unit
Author : Howard Richoux
Date : 2/22/91
Last revised: 12/11/93 fixes
GetKeyInput - added
1/9/94 Sectioned and Sorted
2/8/94 save/restore TEXTATTR
2/18/94 new libraries
2/20/94 Re-Wrote to eliminate TUG units
Changed SAVE procedures to just save the current window
2/21/94 Merged in HKEYstuf
4/25/94 added FetchCRTLine(n) and NewSnapShot for screen reading
Application : IBM PC and compatibles, done in Turbo Pascal 5.5
Status : Placed in the Public Domain by HNR Software 1/29/1994
Published in: none
}
{-}
const ScrnColorSeg = $B800; { Text area of color CGA/EGA/VGA }
const ScrnMonoSeg = $B000; { Text area of MONO card }
const SaveSigniture = $1234; { Unique signiture for already saved }
type savebuf = array[0..3999] of char;
savebufptr = ^savebuf;
type CRTSaveRec = record
signiture : word; { set to SaveSigniture when in use }
scrnsaveptr : savebufptr; { screen buffer on heap }
savebufsize : integer; { amount actually allocated }
cursx, cursy : byte;
x0,y0,x1,y1,attr : byte;
end;
var snapshot : CRTSaveRec; { for FetchCRTLine }
type proctype = procedure;
var HKEY_LastTC : char; { for processing function key exits }
var ScrnClr, PrmptClr, DatClr, MptClr, NtrClr : byte;
SavedAttribute : byte;
type charset = set of char;
{+}
Function InputStr(Y, X : integer; Prompt : string;
var St : string; l : integer; Fn : char; var TC : char) : boolean;
{[CRT] antique routine}
Procedure DisplayStr(Y, X : integer; S : string);
{[CRT] antique routine}
Procedure Beep; {[CRT] sends ctrl-G}
Function CheckYesNo(s : string; default : char) : boolean;
{[CRT] prompts with s, returns t/f for Y/N answer}
Procedure ColorScheme(n : integer; var Scrn, Prmpt, Dat, Mpt, Ntr : byte);
{[CRT] *Internal mostly* sets a selected color scheme }
Procedure ClrScrn;
{[CRT] clears to ScrnColor }
Procedure DataColor;
{[CRT] sets TextAttr to *internal* DataClr }
Procedure DrawBox(x1,y1,x2,y2:integer);
{[CRT] obsolete proc - Use SimpleWindow}
Procedure EmptyColor;
{[CRT] sets TextAttr to *internal* EmptyClr }
Procedure EntryColor;
{[CRT] sets TextAttr to *internal* EntryClr }
Function FetchCRTLine(lin : integer) : string;
{[CRT] Fetches line stored in snapshot }
Function FunctionKeyDecode(ch : char) : string;
{[CRT] this is called AFTER you know it is a function key }
Function FunctionKeyProcess( var Ch : char; workproc : proctype) : boolean;
{[CRT] Get a key and do some work }
Procedure GetKeyCmdProcess(var Command : string; workproc : proctype);
{[CRT] Special keys ONLY - WORKPROC gets executed repeatedly while waiting}
Procedure GetKeyInputProcess(var str,Command : string; workproc : proctype);
{[CRT] ALL KEYS - WORKPROC gets executed repeatedly while waiting}
Procedure GetKeyCmd(var Command : string);
{[CRT] Special keys ONLY }
Procedure GetKeyInput(var str,Command : string);
{[CRT] ALL KEYS }
Procedure MakeBox(x1,y1,x2,y2:integer);
{[CRT] thrilling}
Procedure NewSnapShot;
{[CRT] Clears old snapshot and takes new one }
Procedure NullProc;
{[CRT] Place holder for workproc in keyboard input}
Procedure Pause; {[CRT] waits for keypressed}
Procedure PromptColor;
{[CRT] sets TextAttr to *internal* PromptClr }
Procedure ReSetNormalVideo;
{[CRT] restore them to previous colors }
Procedure RestoreAttr;
{[CRT] put it back before quitting }
Procedure RestoreCursor;
{[CRT] puts cursor to where it saved it}
Procedure RestoreCRT(var CRTSave : CRTSaveRec);
{[CRT] You provide the buffer}
Procedure SaveAttr;
{[CRT] before doing color schemes save original }
Procedure SaveCursor;
{[CRT] holds cursor position for you}
Procedure SaveCRT(var CRTSave : CRTSaveRec);
{[CRT] You provide the buffer}
Procedure ScrnColor;
{[CRT] sets TextAttr to *internal* ScrnClr }
Procedure ScrollDown( NumLines : byte;
ULx,ULy,LRx,LRy, DAttr : byte);
{[CRT] DOS call, absolute coordinates}
Procedure ScrollUp ( NumLines : byte; { Number of lines to scroll }
ULx,ULy,LRx,LRy, DAttr : byte);
{[CRT] DOS call, absolute coordinates}
Procedure ScrollUpWindow( NumLines : byte; { Number of lines to scroll }
DAttr : byte); { Display attribute }
{[CRT] scrolls the current WINDOW only}
Procedure ScrollDownWindow( NumLines : byte; { Number of lines to scroll }
DAttr : byte); { Display attribute }
{[CRT] scrolls the current WINDOW only}
Procedure SetColorScheme(n : integer);
{[CRT] sets color scheme, 0=B/W 1=blues more later }
Procedure SetReverseVideo;
{[CRT] reverse foreground and background colors }
Procedure SimpleWindow(x0,y0,rows,cols : byte; top,bottom : string;
var CRTSave : CRTSaveRec);
{[CRT] useful window routine }
{SECTION .zImplementation }
IMPLEMENTATION
var savattr : integer;
var xxsave,yysave : word; { local storage for saving cursor }
{SECTION BakGround }
Function BakGround(attr : integer) : byte;
var x : integer;
begin
BakGround := (attr shr 4) and 7;
end;
{SECTION Beep }
Procedure Beep;
begin
write(^G);
end;
{SECTION CheckYesNo }
Function CheckYesNo(s : string; default : char) : boolean;
var ch : char;
begin
CheckYesNo := true;
if UpCase(default) = 'N' then CheckYesNo := false;
write(s);
if UpCase(default) = 'Y' then write(' (Y/n) ')
else write(' (y/N) ');
while not keypressed do begin end;
ch := UpCase(readkey);
writeln(ch);
if ch = 'N' then CheckYesNo := false
else if ch = 'Y' then CheckYesNo := true;
end;
{SECTION DrawBox }
Procedure DrawBox(x1,y1,x2,y2:integer); {obsolete proc - don't use}
begin
CRT.window(1,1,80,25);
MakeBox(x1,y1,x2,y2);
CRT.window(x1+1,y1+1,x2-1,y2-1);
CRT.ClrScr;
end;
{SECTION ForGround }
Function ForGround(attr : integer) : byte;
begin
ForGround := attr and 15;
end;
{SECTION FunctionKeyDecode }
Function FunctionKeyDecode(ch : char) : string;
{ this is called AFTER you know it is a function key }
var s : string;
begin
s := '';
case ch of
'G' : s := '?HOME'; {HOME}
'O' : s := '?END'; {END}
'Q' : s := '?DOWN'; {DOWN}
'I' : s := '?UP'; {UP}
'H' : s := '?UPARR'; {UPArrow}
'P' : s := '?DOWNARR'; {DNArrow}
'K' : s := '?LEFTARR'; {LeftArrow}
'M' : s := '?RIGHTARR'; {RightArrow}
#114 : s := '?SCREENPR'; {^PrtSc}
';' : s := '?FKEY1'; {F1 }
'<' : s := '?FKEY2'; {F2 }
'=' : s := '?FKEY3'; {F3 }
'>' : s := '?FKEY4'; {F4 }
'?' : s := '?FKEY5'; {F5 }
'@' : s := '?FKEY6'; {F6 }
'A' : s := '?FKEY7'; {F7 }
'B' : s := '?FKEY8'; {F9 }
'C' : s := '?FKEY9'; {F9 }
'D' : s := '?FKEY10'; {F10 }
'T' : s := '?SFKEY1'; {SF1 }
'U' : s := '?SFKEY2'; {SF2 }
'V' : s := '?SFKEY3'; {SF3 }
'W' : s := '?SFKEY4'; {SF4 }
'X' : s := '?SFKEY5'; {SF5 }
'Y' : s := '?SFKEY6'; {SF6 }
'Z' : s := '?SFKEY7'; {SF7 }
'[' : s := '?SFKEY8'; {SF9 }
'\' : s := '?SFKEY9'; {SF9 }
']' : s := '?SFKEY10'; {SF10}
else s := '';
end;
FunctionKeyDecode := s;
end;
{SECTION FunctionKeyProcess }
{ Formerly HKEYSTUF }
Function FunctionKeyProcess( var Ch : char; workproc : proctype) : boolean;
var choice,fkeypressed: boolean;
begin
fkeypressed := false;
choice := false;
while not choice do
begin
if keypressed then
begin
Ch := CRT.ReadKey;
if Ch = #0 then
begin
if CRT.keypressed then
begin
Ch := CRT.ReadKey;
fkeypressed := true;
end;
end;
choice := true;
end;
WorkProc;
end;
functionkeyProcess := fkeypressed;
end;
{SECTION GetKeyCmd }
Procedure GetKeyCmd(var Command : string);
var ch : char;
done : boolean;
CmdString, CmdSave : string;
BEGIN
GetKeyCmdProcess(Command,nullproc);
end;
{SECTION GetKeyCmdProcess }
Procedure GetKeyCmdProcess(var Command : string; workproc : proctype);
{ Special key input ONLY - no normal text
WORKPROC gets executed repeatedly while waiting for key input}
var ch : char;
done : boolean;
CmdString, CmdSave : string;
BEGIN
CmdString := '';
done := false;
while (CmdString = '') and not done do
begin
IF FunctionKeyProcess(Ch,workproc) THEN
BEGIN
CmdString := FunctionKeyDecode(ch);
Ch := ' ';
END
else if Ch = #27 then CmdString := '?ESCAPE'
else if Ch = #13 then CmdString := Command
else CmdString := '';
end;
Command := CmdString;
end;
{SECTION GetKeyInput }
Procedure GetKeyInput(var str,Command : string);
{ Get an input string and a terminating command (like a fkey)}
var ch : char;
done : boolean;
CmdString, CmdSave : string;
BEGIN
GetKeyInputProcess(str,Command,nullproc);
end;
{SECTION GetKeyInputProcess }
Procedure GetKeyInputProcess(var str,Command : string; workproc : proctype);
{ Special key input AND normal text
WORKPROC gets executed repeatedly while waiting for key input}
var ch : char;
x,y : byte;
done : boolean;
CmdString, CmdSave : string;
BEGIN
CmdString := '';
str := '';
done := false;
while (CmdString = '') and not done do
begin
IF FunctionKeyProcess(Ch,workproc) THEN
BEGIN
CmdString := FunctionKeyDecode(ch);
END
else if Ch = #27 then CmdString := '?ESCAPE'
else if Ch = #13 then CmdString := Command { give back default }
else if Ch = #8 then {backspace}
begin
if length(str) > 0 then
begin
x := WhereX; y := WhereY;
if x > 1 then dec(x)
else begin x := 80; if y>1 then dec(y); end;
gotoXY(x,y);
write(' ');
gotoXY(x,y);
delete(str,length(str),1);
end
end
else begin
CmdString := '';
write(ch);
str := str + ch;
end;
end;
Command := CmdString;
end;
{SECTION MakeAttr }
Function MakeAttr(forgnd,bakgnd : integer) : byte;
begin
MakeAttr := ((bakgnd and 7) shl 4) or (forgnd and 15);
end;
{SECTION MakeBox }
Procedure MakeBox(x1,y1,x2,y2:integer);
const ULcorner = chr(201);
URcorner = chr(187);
LLcorner = chr(200);
LRcorner = chr(188);
HBAR = chr(205);
VBAR = chr(186);
var i:integer;
begin
CRT.highvideo;
CRT.gotoxy(x1,y1);
write(ulcorner);
for i:=x1+1 to x2-1 do write(hbar);
write(urcorner);
for i:=y1+1 to y2-1 do
begin
CRT.gotoxy(x1,i); write(vbar);
CRT.gotoxy(x2,i); write(vbar);
end;
CRT.gotoxy(x1,y2); write(llcorner);
for i:=x1+1 to x2-1 do write(hbar);
write(lrcorner);
CRT.normvideo;
end;
{SECTION NullProc }
Procedure NullProc; begin end;
{SECTION Pause }
Procedure Pause;
var ch : char;
begin
ch := CRT.readkey;
end;
{SECTION ReSetNormalVideo }
Procedure ReSetNormalVideo;
begin
textattr := savattr;
end;
{SECTION RestoreCursor }
Procedure RestoreCursor;
begin
CRT.GOTOXY(xxsave,yysave);
end;
{SECTION SaveCursor }
Procedure SaveCursor;
begin
xxsave := CRT.wherex;
yysave := CRT.wherey;
end;
{SECTION ScrollDown }
Procedure ScrollDown( NumLines : byte; { Number of lines to scroll }
ULx,ULy,LRx,LRy, DAttr : byte);
const IntrCall = 16; { ROM Video BIOS call }
ServiceCall = 7; { Scroll window down service }
var SDDOSRec : Registers;
begin
with SDDOSRec do
begin
AH := ServiceCall;
AL := NumLines;
CH := ULy - 1;
CL := ULx - 1;
DH := LRy - 1;
DL := LRx - 1;
BH := DAttr
end; { WITH }
INTR(IntrCall, SDDOSRec)
end; { ScrollDown }
{SECTION ScrollUp }
Procedure ScrollUp ( NumLines : byte; { Number of lines to scroll }
ULx,ULy,LRx,LRy, DAttr : byte);
const IntrCall = 16; { ROM Video BIOS call }
ServiceCall = 6; { Scroll window up service }
var SDDOSRec : Registers;
begin
with SDDOSRec do
begin
AH := ServiceCall;
AL := NumLines;
CH := ULy - 1;
CL := ULx - 1;
DH := LRy - 1;
DL := LRx - 1;
BH := DAttr
end; { WITH }
INTR(IntrCall, SDDOSRec)
end; { ScrollUp }
{SECTION ScrollUpWindow }
Procedure ScrollUpWindow( NumLines : byte; { Number of lines to scroll }
DAttr : byte); { Display attribute }
var x0,y0,x1,y1 : byte;
begin
x0 := lo(WindMin)+1;
y0 := hi(WindMin)+1;
x1 := lo(WindMax)+1;
y1 := hi(WindMax)+1;
ScrollUp(NumLines,x0,y0,x1,y1,Dattr);
end;
{SECTION ScrollDownWindow }
Procedure ScrollDownWindow( NumLines : byte; { Number of lines to scroll }
DAttr : byte); { Display attribute }
var x0,y0,x1,y1 : byte;
begin
x0 := lo(WindMin)+1;
y0 := hi(WindMin)+1;
x1 := lo(WindMax)+1;
y1 := hi(WindMax)+1;
ScrollDown(NumLines,x0,y0,x1,y1,Dattr);
end;
{SECTION SetReverseVideo }
Procedure SetReverseVideo;
begin
savattr := textattr;
textattr := MakeAttr(BakGround(textattr),ForGround(textattr));
end;
{SECTION SimpleWindow }
Procedure SimpleWindow(x0,y0,rows,cols : byte; top,bottom : string;
var CRTSave : CRTSaveRec);
var x1,y1,l : byte;
begin
x1 := x0 + cols + 2;
y1 := y0 + rows + 1;
CRT.window(x0,y0,x1,y1);
SaveCRT(CRTSave);
CRT.window(1,1,80,25);
MakeBox(x0,y0,x1,y1);
if top <> '' then
begin
l := 1;
if length(top) < (cols - 2) then
l := ((x0 + (cols div 2)) - (length(top) div 2)) - 1;
CRT.gotoxy(l,y0);
write(top);
end;
if bottom <> '' then
begin
l := 1;
if length(bottom) < (cols - 2) then
l := ((x0 + (cols div 2)) - (length(bottom) div 2)) - 1;
CRT.gotoxy(l,y1);
write(bottom);
end;
CRT.window(x0+1,y0+1,x1-1,y1-1);
CRT.clrscr;
end;
{PAGE}
{SECTION RestoreCRTWindow }
Procedure RestoreCRTWindow(var CRTSave : CRTSaveRec);
{[CRT] - hard coding for COLOR screen 25x80 - adapt later}
var err,i : integer;
rows, cols, rowbytes, screenoffset, saveoffset : integer;
screenptr,saveptr : pointer;
begin
screenptr := PTR(ScrnColorSeg,0);
saveoffset := 0;
with CRTSave do
begin
rows := (y1 - y0) + 1;
cols := (x1 - x0) + 1;
rowbytes := cols * 2; { char + attr }
savebufsize := rows * cols * 2;
for i := y0 to y1 do
begin
screenoffset := ((i-1) * 160) + (x0 - 1) * 2;
screenptr := PTR(ScrnColorSeg,screenoffset);
move(scrnsaveptr^[saveoffset], screenptr^, rowbytes);
saveoffset := saveoffset + rowbytes;
end;
if savebufsize > 0 then FreeMem(scrnsaveptr,savebufsize);
savebufsize := 0;
signiture := 0; { mark as not used }
end;
end;
{SECTION SaveCRTWindow }
Procedure SaveCRTWindow(var CRTSave : CRTSaveRec);
{[CRT] - hard coding for COLOR screen 25x80 - adapt later}
var err,i : integer;
rows, cols, rowbytes, screenoffset, saveoffset : integer;
screenptr,saveptr : pointer;
begin
if CRTSave.signiture = SaveSigniture then exit;
screenptr := PTR(ScrnColorSeg,0);
saveoffset := 0;
with CRTSave do
begin
scrnsaveptr := NIL;
rows := (y1 - y0) + 1;
cols := (x1 - x0) + 1;
rowbytes := cols * 2; { char + attr }
savebufsize := rows * cols * 2;
GetMem(scrnsaveptr,savebufsize);
signiture := SaveSigniture; { mark as buffer used }
for i := y0 to y1 do
begin
screenoffset := ((i-1) * 160) + (x0 - 1) * 2;
screenptr := PTR(ScrnColorSeg,screenoffset);
move(screenptr^,scrnsaveptr^[saveoffset],rowbytes);
saveoffset := saveoffset + rowbytes;
end;
end;
end;
{SECTION RestoreCRT }
Procedure RestoreCRT(var CRTSave : CRTSaveRec);
{var currcurstype : cursortype;}
begin
if CRTSave.signiture <> SaveSigniture then exit;
with CRTSave do
begin
RestoreCRTWindow(CRTSave);
CRT.window(CRTSave.x0,CRTSave.y0,CRTSave.x1,CRTSave.y1);
CRT.gotoxy(cursx,cursy);
TEXTATTR := CRTSave.attr;
{ if currcurstype <> curstype then SetCursor(curstype);}
end;
end;
{SECTION SaveCRT }
Procedure SaveCRT(var CRTSave : CRTSaveRec);
begin
if CRTSave.signiture = SaveSigniture then
begin
writeln('** already saved ** [',CRTSave.signiture,']');
exit;
end;
with CRTSave do
begin
cursx := wherex;
cursy := wherey;
x0 := lo(WindMin)+1;
y0 := hi(WindMin)+1;
x1 := lo(WindMax)+1;
y1 := hi(WindMax)+1;
attr := TEXTATTR;
SaveCRTWindow(CRTSave);
end;
end;
{SECTION ClearSaveCRT }
Procedure ClearSaveCRT(var CRTSave : CRTSaveRec);
begin
if CRTSave.signiture <> SaveSigniture then exit;
with CRTSave do
begin
if savebufsize > 0 then FreeMem(scrnsaveptr,savebufsize);
savebufsize := 0;
signiture := 0; { mark as not used }
cursx := wherex;
cursy := wherey;
x0 := lo(WindMin)+1;
y0 := hi(WindMin)+1;
x1 := lo(WindMax)+1;
y1 := hi(WindMax)+1;
attr := TEXTATTR;
end;
end;
{ HKEYstuf merged in (again) 2/21/94 }
Procedure ScrnColor; begin LowVideo; Textbackground(ScrnClr); end;
Procedure PromptColor; begin Scrncolor; TextColor(PrmptClr); end;
Procedure DataColor; begin ScrnColor; Textcolor(DatClr); end;
Procedure EmptyColor; begin ScrnColor; TextBackground(MptClr);TextColor(15); end;
Procedure EntryColor; begin ScrnColor; TextBackground(NtrClr);TextColor(15); end;
Procedure SaveAttr; begin SavedAttribute := TextAttr; end;
Procedure RestoreAttr; begin TextAttr := SavedAttribute; end;
Procedure SetColorScheme(n : integer);
begin
ColorScheme(n,ScrnClr,PrmptClr,DatClr,MptClr,NtrClr);
end;
Procedure ClrScrn; begin ScrnColor; CRT.Clrscr; end;
Procedure ColorScheme(n : integer; var Scrn, Prmpt, Dat, Mpt, Ntr : byte);
begin
{Scrn = basic color of screen
Prmpt = text color of prompt, background is Screen color
Dat = text color for data fields not being entered
Mpt = color of whole entry block
Ntr = background for text being entered
}
case n of
0 : begin { Gray/black/white }
Scrn := 0; Prmpt := 7; Dat := 7; Mpt := 8; Ntr := 8;
end;
1 : begin { Blues }
Scrn := 3; Prmpt := 9; Dat := 1; Mpt := 9; Ntr := 1;
end;
2 : begin { Greens }
Scrn := 2; Prmpt :=9; Dat := 1; Mpt :=9; Ntr := 1;
end;
3 : begin { Greys }
Scrn := 7; Prmpt :=8; Dat := 15; Mpt :=8; Ntr := 15;
end;
else begin { same as #0 }
Scrn := 0; Prmpt := 7; Dat := 7; Mpt := 8; Ntr := 8;
end;
end;
end;
Procedure ProcessLine;
begin
{dummy}
end;
Function FunctionKey( var Ch : char ) : boolean;
var choice,fkeypressed: boolean;
begin
fkeypressed := false;
choice := false;
while not choice do
begin
if keypressed then
begin
Ch := ReadKey;
if Ch = #0 then
begin
if keypressed then
begin
Ch := ReadKey;
fkeypressed := true;
end;
end;
choice := true;
end;
Processline;
end;
Functionkey := fkeypressed;
end;
Procedure ReadKbd(VAR Ch : CHAR);
begin
if FunctionKey(Ch) then begin end;
end;
Procedure DisplayStr(Y, X : INTEGER; S : string);
begin
if length(S) > (81-X) then S := COPY(S, 1, 81-X);
GoToXY(X,Y);
write(S);
end;
Function ConstantCharStr(C : Char; N : Integer) : string;
{ deliberate duplicate of PbMISC routine CONSTSTR }
var S : string;
begin
if N < 0 then N := 0;
S[0] := Chr(N);
FillChar(S[1],N,C);
ConstantCharStr := s;
end;
{PAGE}
Function InputStr(Y, X : INTEGER;
Prompt : string;
VAR St : string;
L : INTEGER;
Fn : CHAR;
VAR TC : CHAR) : BOOLEAN;
{ Functions: U - Update, A - Append, O - Diaplay only }
CONST UnderScore = '_';
Term : charset = [^E, ^M, ^X, ^Z];
MinorKeys : charset = [ ^M ];
Fkeyarrow : charset = ['K', 'M']; { LArr, Rarr}
FkeyTerm : charset = ['P', 'H', 'I', 'Q', 'G', 'O'];
VAR { DArr,UArr,Home,end,PgUp,PgDn}
Pl, P : INTEGER;
S : string;
Ch : CHAR;
exitx, firsttime, InsMode, MAJORExit : BOOLEAN;
begin
MAJORExit := false;
firsttime := true; exitx := FALSE; InsMode := true;
P := 0; Ch := ' ';
PromptColor;
Pl := length(Prompt);
if Pl < (X+1) then DisplayStr(Y, X-Pl, Prompt)
else DisplayStr(Y, 1, COPY(Prompt, Pl-X, X));
EmptyColor;
GotoXY(X,Y); write(ConstantCharStr(UnderScore, L));
if (Fn = 'O') then
begin
S := St;
DataColor;
GotoXY(X,Y);
write(S, ConstantCharStr(UnderScore, L-length(S)));
end
else S := '';
if (Fn = 'U') OR (Fn = 'A') then
begin
S := '';
if Fn = 'U' then
begin
S := St;
EmptyColor;
GotoXY(X,Y); write(S, ConstantCharStr(UnderScore, L-length(S)));
end;
repeat
begin
GotoXY(X+P,Y);
if FunctionKey(Ch) then
begin
exitx := FALSE;
case Ch OF {* Function keys for field edit operations *}
'K' {<-} : begin
if Fn = 'A' then exitx := true
else if P > 0 then P := P-1 { LArr }
else Beep;
end;
'M' {->} : begin
if Fn = 'A' then exitx := true
else if P < length(S) then P := P+1 { RArr }
else Beep;
end;
'S' {DEL} : begin
if P < length(S) then
begin
delete(S, P+1, 1);
end;
end;
'R' {INS}: begin
InsMode := not InsMode;
Beep;
end;
'U' : begin Beep; Beep; end; { ? }
else begin {* Function keys for exit *}
if not(Ch IN FkeyTerm) then
begin
exitx := TRUE;
if Ch <> ^M then MAJORExit := true;
end;
end;
end; {of case}
end
else
begin
case Ch OF {* non Function key operations *}
#32..#126 : begin
if firsttime then
begin {clear rest of default }
S := ''; P := 0;
end;
if not InsMode then
begin {Overwrite mode }
if {(P > 0) and} (P < length(s)) then
S[P+1] := Ch
else S := S + Ch;
if P < L then P := P + 1;
Ch := ' ';
end
else begin {Insert mode }
if P < L then
begin
if length(S) = L then
delete(S, L, 1);
if P < L then P := P+1;
insert(Ch, S, P);
Ch := ' ';
end
else Beep;
end;
end;
#27 {esc} : begin
exitx := true;
P := 0;
S := '';
end;
^S { <- } : if P > 0 then P := P-1
else Beep;
^D { -> } : if P < length(S) then P := P+1
else Beep;
^A { ^<- }: P := 0;
^I { ^-> }: P := length(S);
^G {DEL} : if P < length(S) then
begin
delete(S, P+1, 1);
end;
^H, #127 : if P > 0 then {bkspc}
begin
delete(S, P, 1);
P := P-1;
end
else Beep;
^Y {DelEOL}:begin
delete(S, P+1, L);
end;
else begin
if not(Ch in Term) then Beep;
end;
end; {of case}
end; {of if}
EntryColor;
GotoXY(X,Y);
write(S);
EmptyColor;
write(ConstantCharStr(UnderScore, L-length(S)));
GotoXY(X+P,Y);
firsttime := false;
end; {of repeat}
UNTIL (Ch IN Term) OR (Ch IN FkeyTerm) OR exitx;
St := S;
TC := Ch;
if (TC in FKeyTerm) and
not (TC in MinorKeys) then MAJORExit := true;
HKEY_LastTC := TC;
end;{ of Entry Function }
InputStr := MAJORExit;
end;
Procedure NewSnapShot;
{[CRT] Clears old snapshot and takes new one }
begin
ClearSaveCRT(snapshot);
SaveCRT(snapshot);
end;
Function FetchCRTLine(lin : integer) : string;
{[CRT] Fetches line stored in snapshot }
var s : string;
var i : integer;
begin
FetchCRTLine := '';
if (lin<1) or (lin>25) then exit;
if snapshot.signiture <> SaveSigniture then SaveCRT(snapshot);
s := conststr(' ',80);
for i := 0 to 79 do
begin
s[i+1] :=snapshot.scrnsaveptr^[((lin-1)*160)+(i*2)];
end;
FetchCRTLine := s;
end;
{SECTION zzInitialization }
begin {initialization}
savattr := textattr;
SetColorScheme(0); {default B/W}
HKEY_LastTC := '*';
end.